﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharepointSolutionInstaller.Views;
using Microsoft.SharePoint;
using SharepointSolutionInstaller.Resources;
using Microsoft.SharePoint.Administration;
using SharepointSolutionInstaller.Utils.Configuration;


namespace SharepointSolutionInstaller.Utils.SolutionDeployment
{
    public class DeactivateSiteCollectionFeatureCommand : SiteCollectionFeatureCommand
    {
        private List<SPSite> deactivatedSiteCollections;
        Guid solutionId;
        List<Guid?> currentFeatureId;
        internal DeactivateSiteCollectionFeatureCommand(InstallProcess parent,Guid solutionId, List<Guid?> featureId)
            : base(parent)
        {
            this.currentFeatureId = featureId;
            this.solutionId = solutionId;

            deactivatedSiteCollections = new List<SPSite>();
        }

        public List<SPSite> DeactivatedSiteCollections
        {
            get { return deactivatedSiteCollections; }
        }

        internal override string Description
        {
            get { return CommonUIStrings.deactivateSiteCollectionFeatureCommand; }
        }

        protected internal override bool Execute()
        {
            try
            {
                List<Guid?> featureIds = currentFeatureId;

                SPFarm farm = SPFarm.Local;
                SPSolution solution = farm.Solutions[solutionId];
                if (solution != null && solution.Deployed && featureIds != null && featureIds.Count > 0)
                {
                         log.Info(CommonUIStrings.logFeatureDeactivate);

                    //
                    // LFN - Stopped using solution.DeployedWebApplications as it seems to produced a FormatException 
                    // when created a new Guid value. Looks like a bug in SharePoint that we cannot do anything about. 
                    // I have therefore adopted a new strategy by looping through all Web applications.
                    //

                    foreach (SPWebApplication webApp in SPWebService.AdministrationService.WebApplications)
                    {
                        DeactivateFeatures(webApp);
                    }

                    foreach (SPWebApplication webApp in SPWebService.ContentService.WebApplications)
                    {
                        DeactivateFeatures(webApp);
                    }

                    // KML - not sure why JPI didn't just do this above and avoided using the local dictionary
                    // LFN - Agree, local dictionary removed making the following code obsolete.
                    /*
                    foreach (SPSite _spSite in _dicDeactivatedSiteCollections.Values)
                    {
                        deactivatedSiteCollections.Add(_spSite);
                    }
                    DeactivateFeature(deactivatedSiteCollections, featureIds);
                    */
                }
            }

            catch (Exception ex)
            {
                   log.Error(ex.Message, ex);
            }

            return true;
        }

        private void DeactivateFeatures(SPWebApplication webApp)
        {
            List<Guid?> featureIds = currentFeatureId;

            foreach (SPSite siteCollection in webApp.Sites)
            {
                foreach (Guid? featureId in featureIds)
                {
                    if (featureId == null) continue;
                    if (siteCollection.Features[featureId.Value] == null) continue;

                      log.Info(siteCollection.Url + " : " + featureId.Value.ToString());

                    // LFN - Just deactivate the feature right away. No need to use intermidate step with local dictionary.
                    siteCollection.Features.Remove(featureId.Value);

                    // KML - not sure why JPI used this local dictionary
                    //       instead of doing "deactivatedSiteCollections.Add(siteCollection)" here
                    // LFN - Agree no need to do this. Works just fine by deactivating directly.
                    //_dicDeactivatedSiteCollections[siteCollection.Url] = siteCollection;
                }

                // LFN - It is a memory and resource leak to forget this! See http://msdn.microsoft.com/en-us/library/aa973248.aspx
                // LFN - Well, they might be disposed by the system when the installer process dies. But I think it is good coding
                // practice never to forget this. 
                siteCollection.Dispose();
            }
        }
    }
}
